home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / umich / falcon / utils / oszi01.lzh / OSZI.C < prev    next >
C/C++ Source or Header  |  1995-09-17  |  14KB  |  675 lines

  1. /*
  2.     @(#)oszi.c
  3.     Copyright (c) 1995
  4.     Julian F. Reschke /
  5.     Maxon Computer
  6.  
  7.     17. September 1995
  8. */
  9.  
  10. #include <aes.h>
  11. #include <stdio.h>
  12. #include <string.h>
  13. #include <tos.h>
  14. #include <vdi.h>
  15.  
  16. #define PNAME    "DMA-Sound-Oszilloskop"
  17.  
  18. char *
  19. sccsid (void)
  20. {
  21.     return "@(#)"PNAME" 01, Copyright (c) Maxon Computer GmbH/J. Reschke, "__DATE__;
  22. }
  23.  
  24. /* Erweiterungen für PureC */
  25.  
  26. #define SMALLER         0x4000
  27.  
  28. #define WM_BUTTOMED     33
  29. #define WM_ICONIFY      34
  30. #define WM_UNICONIFY    35
  31. #define WM_ALLICONIFY   36
  32.  
  33. #define WF_ICONIFY      26
  34. #define WF_UNICONIFY    27
  35. #define WF_UNICONIFYXYWH    28
  36.  
  37. /* appl_getinfo für AES >= 0x0400 und ältere
  38.    Systeme mit entsprechender Erweiterung */
  39.  
  40. static int
  41. appl_xgetinfo (int type, int *out1, int *out2,
  42.     int *out3, int *out4)
  43. {
  44.     static short hasagi = -1;
  45.  
  46.     if (hasagi < 0)
  47.         hasagi = _GemParBlk.global[0] >= 0x400 ||
  48.             appl_find( "?AGI\0\0\0\0") == 0;
  49.  
  50.     return !hasagi ? 0 :
  51.         appl_getinfo (type, out1, out2, out3, out4);
  52. }
  53.  
  54. /* Mittels appl_getinfo wird abgefragt, ob Iconify
  55.    möglich ist */
  56.  
  57. static int
  58. has_iconify (void)
  59. {
  60.     static int hasit = -1;
  61.  
  62.     if (hasit < 0)
  63.     {
  64.         int dum, val;
  65.  
  66.         hasit = 0;
  67.  
  68.         if (0 != appl_xgetinfo (11, &val, &dum, &dum, &dum))
  69.             if (val & 128)
  70.                 hasit = 1;
  71.     }
  72.  
  73.     return hasit;
  74. }
  75.  
  76.  
  77. /* wind_xset/xget: Varianten, die im Gegensatz zu
  78.    denem in den Pure-C-Libraries auch mit unbekannten
  79.    Opcodes richtig funktioniert */
  80.    
  81. static int    contrl[15];
  82. static int    global[15];
  83. static int    intin[132];
  84. static int    intout[140];
  85. static int    addrin[16];
  86. static int    addrout[16];
  87.  
  88. static AESPB A = { contrl, global, intin,
  89.     intout, addrin, addrout };
  90.  
  91. static int
  92. wind_xget (int handle, int field, int *w1, int *w2,
  93.     int *w3, int *w4)
  94. {
  95.     contrl[0] = 104;
  96.     contrl[1] = 2;
  97.     contrl[2] = 5;
  98.     contrl[3] = contrl[4] = 0;
  99.     intin[0] = handle;
  100.     intin[1] = field;
  101.     _crystal (&A);
  102.     *w1 = intout[1];
  103.     *w2 = intout[2];
  104.     *w3 = intout[3];
  105.     *w4 = intout[4];
  106.     return intout[0];
  107. }
  108.  
  109. static int
  110. wind_xset (int handle, int field, int w1, int w2,
  111.     int w3, int w4)
  112. {
  113.     contrl[0] = 105;
  114.     contrl[1] = 6;
  115.     contrl[2] = 1;
  116.     contrl[3] = contrl[4] = 0;
  117.     intin[0] = handle;
  118.     intin[1] = field;
  119.     intin[2] = w1;
  120.     intin[3] = w2;
  121.     intin[4] = w3;
  122.     intin[5] = w4;
  123.     _crystal (&A);
  124.     return intout[0];
  125. }
  126.  
  127.  
  128. /* Erst hier geht es richtig los */
  129.  
  130. #define HEIGHT    80            /* Fensterhöhe */
  131. #define WIDTH    400            /* Fensterbreite */
  132. #define BPL        WIDTH/8
  133.  
  134. static char wtitle[128] = " "PNAME" ";
  135. static char oszimem[HEIGHT*BPL];
  136. static int colors[] = {0, 1};
  137.  
  138. /* MFDB für die Offscreen-Bitmap, in der alles
  139.    passiert */
  140.  
  141. static MFDB oszimfdb = {
  142.     oszimem,
  143.     WIDTH, HEIGHT,
  144.     BPL / 2,
  145.     1, 1,
  146.     0, 0, 0
  147. };
  148.  
  149. /* MFDB für den Bildschirm (auf 0
  150.    initialisiert */
  151.  
  152. static MFDB screen;
  153.  
  154. static char *offs[256], *loffs[256], *roffs[256];
  155.  
  156. #define byte unsigned char
  157.  
  158. /* die DMA-Sound-Register */
  159.  
  160. short *soundctrl = (short *)0xffff8900L;
  161.  
  162. byte *fbhigh = (byte *)0xffff8903L;
  163. byte *fbmid = (byte *)0xffff8905L;
  164. byte *fblow = (byte *)0xffff8907L;
  165.  
  166. byte *fchigh = (byte *)0xffff8909L;
  167. byte *fcmid = (byte *)0xffff890BL;
  168. byte *fclow = (byte *)0xffff890DL;
  169.  
  170. byte *fehigh = (byte *)0xffff890fL;
  171. byte *femid = (byte *)0xffff8911L;
  172. byte *felow = (byte *)0xffff8913L;
  173.  
  174. short *soundmode = (short *)0xffff8920L;
  175.  
  176.  
  177. /* Aktuelle Parameter der Soundhardware
  178.    erfragen */
  179.  
  180. static void
  181. getsnddata (int *mode, int *ctrl,
  182.     long *adr, long *end)
  183. {
  184.     long oldsp = Super (0L);
  185.     char *d = (char *)adr;
  186.     char *e = (char *)end;
  187.  
  188.     *mode = *soundmode;
  189.     *ctrl = *soundctrl;
  190.     *d++ = 0;
  191.     *d++ = *fchigh;
  192.     *d++ = *fcmid;
  193.     *d = *fclow;
  194.     *e++ = 0;
  195.     *e++ = *fehigh;
  196.     *e++ = *femid;
  197.     *e = *felow;
  198.  
  199.     Super ((void *)oldsp);
  200. }
  201.  
  202. /* Tabellen für Bitmapausgabe
  203.    vorberechnen */
  204.  
  205. static void
  206. init_table (void)
  207. {
  208.     char **d = offs;
  209.     char **r = roffs;
  210.     char **l = loffs;
  211.     int i;
  212.  
  213.     for (i = 0; i < 128; i++)
  214.     {
  215.         *d++ = oszimem + (HEIGHT/2 +
  216.             (i * HEIGHT/2) / 128) * BPL;
  217.         *l++ = oszimem + (HEIGHT/3 +
  218.             (i * HEIGHT/3) / 128) * BPL;
  219.         *r++ = oszimem + (HEIGHT*2/3 +
  220.             (i * HEIGHT/3) / 128) * BPL;
  221.     }
  222.     for (i = -128; i < 0; i++)
  223.     {
  224.         *d++ = oszimem + (HEIGHT/2 +
  225.             (i * HEIGHT/2) / 128) * BPL;
  226.         *l++ = oszimem + (HEIGHT/3 +
  227.             (i * HEIGHT/3) / 128) * BPL;
  228.         *r++ = oszimem + (HEIGHT*2/3 +
  229.             (i * HEIGHT/3) / 128) * BPL;
  230.     }
  231. }
  232.  
  233. /* Bitmap berechnen */
  234.  
  235. static int
  236. disp (int *mode)
  237. {
  238.     static int bla = 0x01;
  239.     int control;
  240.     unsigned char *adr, *end;
  241.     int i;
  242.  
  243.     getsnddata (mode, &control,
  244.         (long *)&adr, (long *)&end);
  245.  
  246.     /* DMA-Sound aktiv? */
  247.     if (control & 1)
  248.     {
  249.         int mask = 1 << (bla++ & 7);
  250.  
  251.         memset (oszimem, 0, sizeof (oszimem));
  252.  
  253.         /* Stereo oder Mono? */
  254.         if (!(*mode & 0x80))
  255.         {
  256.             if ((long)end - (long)adr < WIDTH * 2)
  257.                 adr = end - WIDTH * 2;
  258.  
  259.             memset (loffs[0], mask, BPL);
  260.             memset (roffs[0], mask, BPL);
  261.  
  262.             for (i = 0; i < BPL; i++)
  263.             {
  264.                 loffs[*adr++][i] ^= 0x80;
  265.                 roffs[*adr++][i] ^= 0x80;
  266.                 loffs[*adr++][i] ^= 0x40;
  267.                 roffs[*adr++][i] ^= 0x40;
  268.                 loffs[*adr++][i] ^= 0x20;
  269.                 roffs[*adr++][i] ^= 0x20;
  270.                 loffs[*adr++][i] ^= 0x10;
  271.                 roffs[*adr++][i] ^= 0x10;
  272.                 loffs[*adr++][i] ^= 0x8;
  273.                 roffs[*adr++][i] ^= 0x8;
  274.                 loffs[*adr++][i] ^= 0x4;
  275.                 roffs[*adr++][i] ^= 0x4;
  276.                 loffs[*adr++][i] ^= 0x2;
  277.                 roffs[*adr++][i] ^= 0x2;
  278.                 loffs[*adr++][i] ^= 0x1;
  279.                 roffs[*adr++][i] ^= 0x1;
  280.             }
  281.         }
  282.         else
  283.         {
  284.             if ((long)end - (long)adr < WIDTH)
  285.                 adr = end - WIDTH;
  286.  
  287.             memset (oszimem + BPL * HEIGHT/2,
  288.                 mask, BPL);
  289.  
  290.             for (i = 0; i < BPL; i++)
  291.             {
  292.                 offs[*adr++][i] ^= 0x80;
  293.                 offs[*adr++][i] ^= 0x40;
  294.                 offs[*adr++][i] ^= 0x20;
  295.                 offs[*adr++][i] ^= 0x10;
  296.                 offs[*adr++][i] ^= 0x8;
  297.                 offs[*adr++][i] ^= 0x4;
  298.                 offs[*adr++][i] ^= 0x2;
  299.                 offs[*adr++][i] ^= 0x1;
  300.             }
  301.         }
  302.     }
  303.  
  304.     return control;
  305. }
  306.  
  307. #define MAX(a,b) ((a>b)?a:b)
  308. #define MIN(a,b) ((a<b)?a:b)
  309.  
  310. static int
  311. rect_inter (int x1, int y1, int w1,
  312.     int h1, int x2, int y2, int w2,
  313.     int h2, int *x3, int *y3, int *w3, int *h3)
  314. {
  315.     int t1,t2;
  316.  
  317.     *x3 = MAX(x1,x2);
  318.     *y3 = MAX(y1,y2);
  319.     t1 = x1+w1; t2 = x2+w2;
  320.     *w3 = MIN(t1,t2) - *x3;
  321.     t1 = y1+h1; t2 = y2+h2;
  322.     *h3 = MIN(t1,t2) - *y3;
  323.     return((*w3>0)&&(*h3>0));
  324. }
  325.  
  326. static int
  327. redraw (int whandle, int vdihandle,
  328.     int lastmode, int orgx, int orgy, int cx, int cy,
  329.     int cw, int ch, int force)
  330. {
  331.     int dx, dy, dw, dh;
  332.     int newmode;
  333.     int ctl = disp (&newmode);
  334.  
  335.     /* hat sich der Soundmode geändert? */
  336.     if (newmode != lastmode)
  337.     {
  338.         int rate = newmode & 3;
  339.         char *str[] = {"6.25", "12.5", "25", "50"};
  340.         char *s = wtitle;
  341.  
  342.         s += sprintf (s, " "PNAME" ");
  343.         if (ctl & 1)
  344.             sprintf (s, "[%s KHz] ", str[rate]);
  345.  
  346.         wind_set (whandle, WF_NAME, wtitle);
  347.     }
  348.  
  349.     if (!force && !(ctl & 1)) return newmode;
  350.  
  351.     wind_update (BEG_UPDATE);
  352.     wind_get (whandle, WF_FIRSTXYWH,
  353.         &dx, &dy, &dw, &dh);
  354.  
  355.     graf_mouse (M_OFF, 0);
  356.     while (dw && dh)
  357.     {
  358.         int x1, y1, w1, h1;
  359.  
  360.         if (rect_inter (cx, cy, cw, ch,
  361.             dx, dy, dw, dh, &x1, &y1, &w1, &h1))
  362.         {
  363.             int pxy[8];
  364.  
  365.             pxy[0] = x1 - orgx;
  366.             pxy[1] = y1 - orgy;
  367.             pxy[2] = pxy[0] + w1 - 1;
  368.             pxy[3] = pxy[1] + h1 - 1;
  369.             pxy[4] = x1; pxy[5] = y1;
  370.             pxy[6] = x1 + w1 - 1;
  371.             pxy[7] = y1 + h1 - 1;
  372.  
  373.             vrt_cpyfm (vdihandle, MD_REPLACE, pxy,
  374.                 &oszimfdb, &screen, colors);
  375.         }
  376.  
  377.         wind_get (whandle, WF_NEXTXYWH,
  378.             &dx, &dy, &dw, &dh);
  379.     }
  380.  
  381.     wind_update (END_UPDATE);
  382.     graf_mouse (M_ON, 0);
  383.     return newmode;
  384. }
  385.  
  386. /* Fenster öffnen bzw schließen */
  387.  
  388. static int
  389. open_window (int *x, int *y, int *w, int *h)
  390. {
  391.     int handle;
  392.     int wx, wy, ww, wh;
  393.  
  394.     wind_calc (WC_BORDER, NAME|CLOSER|MOVER|SMALLER,
  395.         96, 100, WIDTH, HEIGHT, &wx, &wy, &ww, &wh);
  396.     handle = wind_create (NAME|CLOSER|MOVER|SMALLER,
  397.         wx, wy, ww, wh);
  398.  
  399.     if (handle >= 0) {
  400.         wind_set (handle, WF_NAME, wtitle);
  401.         wind_open (handle, wx, wy, ww, wh);
  402.         wind_get (handle, WF_WORKXYWH, x, y, w, h);
  403.     }
  404.     else
  405.         form_alert (1, "[1][ Konnte Fenster|"
  406.             "nicht öffnen!][ OK ]");
  407.     
  408.     return handle;
  409. }
  410.  
  411.